﻿using IR.Common.Enums;
using IR.Common.Utilities;
using IR.Controller.ModelControllers;
using IR.Model.Models;
using IR.WPF.ViewModels.LandingViewModels;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace IR.WPF.UI.ViewModels
{
    public class VMIdeaDetail : ViewModelBase
    {
        private string _title;
        private int _ideaID;
        private CVersion _version;
        private string _description;
        private Category _category;
        private Status _status;
        private CUser _creator;
        private CUser _assignee;
        private VMNote[] _notes = new VMNote[0];
        private DateTime _dateCreated;
        private DateTime? _lastUpdated;
        private VMViewPage _parentContext;

        private ICommand _createNoteCommand;

        public VMIdeaDetail(Window boundWindow)
        {
            BoundWindow = boundWindow;
            MainWindow window = App.Current.MainWindow as MainWindow;
            window.PropertyChanged += IdeaPropertyChanged;
            _parentContext = BoundWindow.DataContext as VMViewPage;
            _parentContext.PropertyChanged += IdeaPropertyChanged;
        }

        public override void DoCleanup()
        {
            MainWindow window = App.Current.MainWindow as MainWindow;
            window.PropertyChanged -= IdeaPropertyChanged;
            _parentContext = BoundWindow.DataContext as VMViewPage;
            _parentContext.PropertyChanged -= IdeaPropertyChanged;
            window.CurrentlySelectedIdea = null;
        }

        #region **Properties**
        public string Title
        {
            get
            {
                if (_title == null)
                    return "No Idea Selected";

                return (_title);
            }
            private set { _title = value; _parentContext.NotifyPropertyChanged("Title", this); }
        }

        public string Version
        {
            get
            {
                if (_version == null)
                    return string.Empty;
                return (_version.VersionID);
            }
            private set { _version = new CVersion(value); _parentContext.NotifyPropertyChanged("Version", this); }
        }

        public string Description
        {
            get
            {
                if (_description == null)
                    return string.Empty;
                return (_description);
            }
            private set { _description = value; _parentContext.NotifyPropertyChanged("Description", this); }
        }

        public string Category
        {
            get { return (_category.ToString()); }
            private set { _category = (Category) Enum.Parse(typeof(Category), value); _parentContext.NotifyPropertyChanged("Category", this); }
        }

        public string Status
        {
            get { return (_status.ToString()); }
            private set { _status = (Status) Enum.Parse(typeof(Status), value); _parentContext.NotifyPropertyChanged("Status", this); }
        }

        public string Creator
        {
            get
            {
                if (_creator == null)
                {
                    return string.Empty;
                }
                return (_creator.Username);
            }
            private set { _creator = new CUser(value); _parentContext.NotifyPropertyChanged("Creator", this); }
        }

        public string Assignee
        {
            get
            {
                if (_assignee == null)
                {
                    return string.Empty;
                }
                return (_assignee.Username);
            }
            private set
            {
                if (string.IsNullOrEmpty(value))
                {
                    _assignee = new CUser(value);
                }
                else
                {
                    _assignee = null;
                }

                _parentContext.NotifyPropertyChanged("Assignee", this);
            }
        }

        public VMNote[] Notes
        {
            get
            {
                if (_ideaID == 0)
                {
                    _notes = new VMNote[0];
                }
                else
                {
                    Query query = new Query();
                    query.Queries.Add(Query.NotesColumns.Idea, MIdea.Load(_ideaID));

                    try
                    {
                        //Make this async
                        _notes = CNote.QueryNotes(query)
                            .Where(no => no.Idea.IdeaID == _ideaID).ToList()
                            .OrderByDescending(no => no.DateCreated)
                            .Select(idea => new VMNote(idea))
                            .ToArray();
                    }
                    catch
                    {
                        _notes = new VMNote[0];
                    }
                }

                return _notes;
            }
        }

        public string DateCreated
        {
            get { return (_dateCreated.ToString()); }
            private set { _dateCreated = DateTime.Parse(value); _parentContext.NotifyPropertyChanged("DateCreated", this); }
        }

        public string LastUpdated
        {
            get
            {
                if (_lastUpdated == null)
                {
                    return ("Never Updated");
                }

                return (_lastUpdated.ToString());
            }
            private set
            {
                if (value != null)
                {
                    _lastUpdated = DateTime.Parse(value);
                }
                else
                {
                    _lastUpdated = null;
                }

                _parentContext.NotifyPropertyChanged("LastUpdated", this);
            }
        }
        #endregion

        #region **INotifyProperties**
        public void IdeaPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "CurrentlySelectedIdea")
            {
                MainWindow window = App.Current.MainWindow as MainWindow;
                Title = window.CurrentlySelectedIdea.IdeaController.Title;
                Version = window.CurrentlySelectedIdea.IdeaController.Version.VersionID;
                Description = window.CurrentlySelectedIdea.IdeaController.Description;
                Category = window.CurrentlySelectedIdea.IdeaController.Category.ToString();
                Status = window.CurrentlySelectedIdea.IdeaController.Status.ToString();
                Creator = window.CurrentlySelectedIdea.IdeaController.UserCreated.Username;
                if (window.CurrentlySelectedIdea.IdeaController.UserAssigned != null)
                {
                    Assignee = window.CurrentlySelectedIdea.IdeaController.UserAssigned.Username;
                }
                else
                {
                    Assignee = null;
                }
                DateCreated = window.CurrentlySelectedIdea.IdeaController.DateCreated.ToString();
                if (window.CurrentlySelectedIdea.IdeaController.LastUpdated != null)
                {
                    LastUpdated = window.CurrentlySelectedIdea.IdeaController.LastUpdated.ToString();
                }
                else
                {
                    LastUpdated = null;
                }
                if (window.CurrentlySelectedIdea.IdeaId == 0)
                {
                    _ideaID = 0;
                }
                else
                {
                    _ideaID = window.CurrentlySelectedIdea.IdeaId;
                }
                _parentContext.NotifyPropertyChanged("Notes", this);
            }
            else if (e.PropertyName == "ViewPageClosed")
            {
                DoCleanup();
            }
        }
        #endregion

        #region **Commands**
        /// <summary>
        /// Gets a command defined for Edit
        /// </summary>
        public ICommand Edit
        {
            get
            {
                if (_createNoteCommand == null)
                    _createNoteCommand = new RelayCommand(p => CreateNoteFunction(p as Control), p => CanCreateNote(p as Control));

                return _createNoteCommand;
            }
        }
        #endregion

        #region **Command Functions**
        protected void CreateNoteFunction(Control sender)
        {
            // Get a reference to the Window that contained the sender Control
            Window window = Window.GetWindow(sender);

            MessageBox.Show("A create Window");
        }
        #endregion

        #region **CanRun Functions**
        protected bool CanCreateNote(Control sender)
        {
            return true;
        }
        #endregion
    }
}
